<template>
  <div class="flex flex-col h-full bg-gray-100 dark:bg-black overflow-hidden ">
    <!-- 分类 Tabs -->
    <div class="flex-shrink-0 px-4 pt-4 pb-2">
      <CategoryTabs v-model="activeCategoryId" />
    </div>

    <!-- 列表容器 -->
    <div
      class="flex-1 overflow-hidden   "
      @touchstart="handleTouchStart"
      @touchmove="handleTouchMove"
      @touchend="handleTouchEnd"
    >
      <!-- 
        可滑动/可下拉的内部视图。
        它的 transform 由 computedStyle 动态控制。
      -->
      <div
        class="flex flex-col h-full scrollbar-hide "
        :style="computedStyle"
      >
        <!-- 
          滚动容器。
          注意：下拉刷新的提示 div 现在在它的 *外面*，这是实现下拉效果的关键。
        -->
        <div 
          ref="scrollTipRef"
          class="flex-shrink-0 flex justify-center items-center h-16 text-gray-500"
          :style="{ opacity: pullDownOpacity }"
        >
          <svg v-if="isRefreshing" class="animate-spin h-5 w-5 mr-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>
          <span>{{ pullDownText }}</span>
        </div>
        <div class="flex-1 overflow-y-auto scrollbar-hide  min-h-0" id="home-scroll-container" ref="scrollContainer">
          <CategoryList :key="activeCategoryId" :category-id="activeCategoryId" />
        </div>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
export default {
  name: 'Home'
}
</script>
<script setup lang="ts">
import { ref, onMounted, computed, watch, nextTick } from 'vue';
import CategoryTabs from './components/CategoryTabs.vue';
import CategoryList from './components/CategoryList.vue';
import { useCategoryStore } from '@/store/modules/category';
import { usePexelsStore } from '@/store/modules/pexels';

const categoryStore = useCategoryStore();
const pexelsStore = usePexelsStore();

const activeCategoryId = ref<string>('');
const scrollContainer = ref<HTMLElement | null>(null);
const scrollTipRef = ref<HTMLElement | null>(null);

// --- 状态管理 ---
const isTouching = ref(false);      // 标记是否正在触摸
const isDragging = ref(false);      // 标记是否正在拖动（横向或纵向）
const isAnimating = ref(false);     // 标记是否正在执行切换动画，防止重复触发
const isRefreshing = ref(false);    // 标记是否正在执行刷新动作
const dragDirection = ref<'horizontal' | 'vertical' | null>(null); // 拖动方向

// --- 坐标与位移 ---
const touchStartX = ref(0);
const touchStartY = ref(0);
const deltaX = ref(0);
const deltaY = ref(0);
const ANIMATION_DURATION = 100; // 回弹动画执行时间

// --- 下拉刷新相关 ---
const PULL_DOWN_THRESHOLD = 70;
const pullDownTipHeight = ref(64);
const pullDownOpacity = ref(0);
const pullDownText = ref('下拉刷新');

// --- 左右滑动相关 ---
const SWIPE_THRESHOLD = 50;

// 【优化点】动态计算样式
const computedStyle = computed(() => {
  // 下拉的 Y 轴位移，只在纵向拖动时生效
  const pullDownY = dragDirection.value === 'vertical' ? Math.max(0, deltaY.value - pullDownTipHeight.value) : 0;
  
  return {
    // 使用 translate3d 开启硬件加速，性能更好
    transform: `translate3d(${deltaX.value}px, ${pullDownY}px, 0)`,
    // 只有在非触摸、非拖动状态下，才应用过渡动画（用于实现切换和回弹）
    transition: !isTouching.value && !isDragging.value ? 'transform 0.3s ease-out' : 'none',
    // 将下拉提示向上移动一个自身的高度，初始状态下隐藏它
    marginTop: `-${pullDownTipHeight.value}px`,
    // h-full + 提示高度，确保列表内容区域占满屏幕
    height: `calc(100% + ${pullDownTipHeight.value}px)`,
  };
});

// 监听分类变化，重置滚动条位置
watch(activeCategoryId, () => {
  if (scrollContainer.value) {
    scrollContainer.value.scrollTop = 0;
  }
});

onMounted(async () => {
  // 【优化点】在 onMounted 中获取并存储提示 div 的实际高度
  if (scrollTipRef.value) {
    pullDownTipHeight.value = scrollTipRef.value.clientHeight;
  }
  
  if (categoryStore.list.length === 0) {
    await categoryStore.getCategoryList();
  }
  if (!activeCategoryId.value && categoryStore.list.length > 0) {
    activeCategoryId.value = categoryStore.list[0].id;
  }
});

const handleTouchStart = (e: TouchEvent) => {
  if (isAnimating.value) return; // 如果正在动画中，则忽略触摸

  isTouching.value = true;
  isDragging.value = false;
  dragDirection.value = null;
  deltaX.value = 0;
  deltaY.value = 0;
  touchStartX.value = e.changedTouches[0].clientX;
  touchStartY.value = e.changedTouches[0].clientY;
  pullDownText.value = '下拉刷新';
};

const handleTouchMove = (e: TouchEvent) => {
  if (!isTouching.value || isAnimating.value) return;

  const currentDeltaX = e.changedTouches[0].clientX - touchStartX.value;
  const currentDeltaY = e.changedTouches[0].clientY - touchStartY.value;
  
  // 首次有效移动时判断拖动意图
  if (!isDragging.value) {
    // 超过一个微小阈值才开始判断
    if (Math.abs(currentDeltaX) > 10 || Math.abs(currentDeltaY) > 10) {
      isDragging.value = true;
      dragDirection.value = Math.abs(currentDeltaX) > Math.abs(currentDeltaY) ? 'horizontal' : 'vertical';
    }
  }

  if (isDragging.value) {
    if (dragDirection.value === 'horizontal') {
      e.preventDefault();
      deltaX.value = currentDeltaX;
    } else if (dragDirection.value === 'vertical' && scrollContainer.value?.scrollTop === 0 && currentDeltaY > 0) {
      e.preventDefault();
      deltaY.value = currentDeltaY;
      pullDownOpacity.value = Math.min(1, deltaY.value / PULL_DOWN_THRESHOLD);
      pullDownText.value = deltaY.value > PULL_DOWN_THRESHOLD ? '松开刷新' : '下拉刷新';
    }
  }
};

const handleTouchEnd = async () => {
  if (!isTouching.value || isAnimating.value) return;
  
  isTouching.value = false; // 标记触摸结束，此时 computedStyle 的 transition 会生效

  if (dragDirection.value === 'horizontal' && Math.abs(deltaX.value) > SWIPE_THRESHOLD) {
    // 【优化点】执行左右滑动切换动画
    performSwipeAnimation();
  } else if (dragDirection.value === 'vertical' && deltaY.value > PULL_DOWN_THRESHOLD) {
    // 执行下拉刷新
    performPullDownRefresh();
  } else {
    // 如果不满足任何条件，则平滑地回弹到原位
    deltaX.value = 0;
    deltaY.value = 0;
    pullDownOpacity.value = 0;
  }
  
  // 延迟重置拖动状态，确保回弹动画可以执行
  setTimeout(() => {
    isDragging.value = false;
  }, ANIMATION_DURATION);
};

// 【优化点】封装切换动画逻辑
const performSwipeAnimation = () => {
  isAnimating.value = true;
  const screenWidth = window.innerWidth;
  const currentIndex = categoryStore.list.findIndex(c => c.id === activeCategoryId.value);
  let nextIndex = currentIndex;

  if (deltaX.value < 0) { // 向左滑
    deltaX.value = -screenWidth; // 动画：滑出到左边
    nextIndex = Math.min(currentIndex + 1, categoryStore.list.length - 1);
  } else { // 向右滑
    deltaX.value = screenWidth; // 动画：滑出到右边
    nextIndex = Math.max(currentIndex - 1, 0);
  }
  // 在滑出动画结束后执行
  setTimeout(() => {
    if (currentIndex !== nextIndex) {
      activeCategoryId.value = categoryStore.list[nextIndex].id;
    }
    // 瞬间移动到另一侧，准备滑入
    isTouching.value = true; // 临时关闭 transition
    deltaX.value = -Math.sign(deltaX.value) * screenWidth; // 如果从左边滑出，就从右边进来
    
    // 使用 nextTick 确保 DOM 更新后再开启动画
    nextTick(() => {
      isTouching.value = false; // 重新开启 transition
      deltaX.value = 0; // 动画：滑入到中心
      // 在滑入动画结束后，解锁触摸
      setTimeout(() => {
        isAnimating.value = false;
      }, ANIMATION_DURATION);
    });
  }, ANIMATION_DURATION);
};

// 【优化点】封装下拉刷新逻辑
const performPullDownRefresh = async () => {
  isRefreshing.value = true;
  pullDownText.value = '正在刷新...';
  deltaY.value = PULL_DOWN_THRESHOLD; // 固定在触发位置，提供更好的视觉反馈

  await pexelsStore.refreshList(activeCategoryId.value);

  // 刷新结束后，平滑地收起
  deltaY.value = 0;
  pullDownOpacity.value = 0;
  isRefreshing.value = false;
};
</script>
<style scoped>
/* 
  【优化点】自定义 PC 端滚动条样式
  可以放在 App.vue 的 <style> 中作为全局样式，或放在这里。
*/
.custom-scrollbar::-webkit-scrollbar {
  width: 6px; /* 滚动条宽度 */
}

.custom-scrollbar::-webkit-scrollbar-track {
  background: transparent; /* 轨道背景 */
}

.custom-scrollbar::-webkit-scrollbar-thumb {
  background: #ccc; /* 滑块颜色 */
  border-radius: 3px; /* 滑块圆角 */
}

.custom-scrollbar::-webkit-scrollbar-thumb:hover {
  background: #999; /* 鼠标悬停时滑块颜色 */
}
</style>